<?php


namespace App\Traits;

use Alipay\EasySDK\Kernel\Config;
use Alipay\EasySDK\Kernel\Factory;
use App\Models\Log\RefundLog;
use App\Models\Member\Member;
use App\Models\Log\CashLog;
use App\Models\Log\PayLog;
use App\Models\User\Recharge;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

trait AliPay {
	function __construct() {
		//1. 设置参数（全局只需设置一次）
		Factory::setOptions( $this->getOptions() );

	}

	//配置信息
	private function getOptions() {
		$options              = new Config();
		$options->protocol    = 'https';
		$options->gatewayHost = 'openapi.alipay.com';
		$options->signType    = 'RSA2';

		// APPID
		$options->appId = config( 'base.alipay.ALIPAY_appId' );
		// 私钥
		$options->merchantPrivateKey = config( 'base.alipay.ALIPAY_merchantPrivateKey' );
		// 支付宝公钥
		$options->alipayPublicKey = config( 'base.alipay.ALIPAY_alipayPublicKey' );
		// 异步通知
		$options->notifyUrl = url( '/alipay/notify_url' );

		return $options;
	}

	//电脑网站支付
	public function AliPay_Pc_Pay( $subject, $outTrandeNo, $totalAmount ) {
		try {
			$result = Factory::payment()->page()->pay( $subject, $outTrandeNo, $totalAmount,
				url( '/alipay/return_url' ) );
			if ( ! empty( $result->body ) ) {
				//调用成功
				$res = $result->body;
			} else {
				$res = "调用失败";
			}
		} catch ( Exception $e ) {
			$res = "调用失败，" . $e->getMessage() . PHP_EOL;
		}

		return $res;
	}

	//手机网站支付
	public function AliPay_Wap_Pay( $subject, $outTrandeNo, $totalAmount ) {
		try {
			$result = Factory::payment()->wap()->pay( $subject, $outTrandeNo, $totalAmount, url( '/funds/recharge' ),
				url( '/alipay/return_url' ) );
			if ( ! empty( $result->body ) ) {
				//调用成功
				$res = $result->body;
			} else {
				$res = "调用失败";
			}
		} catch ( Exception $e ) {
			$res = "调用失败，" . $e->getMessage() . PHP_EOL;
		}

		return $res;
	}


	// 异步回调
	public function AliPay_Notify_Url() {
		$arr = request()->all();
		//验签
		$res = @Factory::payment()->common()->verifyNotify( $arr );
		if ( $res ) {
			//验签成功
			if ( $arr['trade_status'] == "TRADE_SUCCESS" ) {
				$recharge = Recharge::where( 'out_trade_no', $arr['out_trade_no'] )->where( 'pay_status',
					false )->first();
				if ( ! $recharge ) {
					return '已支付';
				}
				//开启事务
				DB::beginTransaction();
				try {
					$recharge->update( [ 'pay_status' => true, 'total_amount' => $arr['total_amount'] ] );
					$member = Member::where( 'id', $recharge->user_id )->first();


					//写支付日志
					$pay_log_data = [
						'user_id'      => $recharge->user_id,
						'out_trade_no' => $recharge->out_trade_no,
						'pay_type'     => 1, //'支付类型 管理员充值:0 支付宝:1 微信:2'
						'total_amount' => $recharge->total_amount,
					];
					PayLog::create( $pay_log_data );

					//写CASH 日志
					$cash_log_data = [
						'user_id'      => $recharge->user_id,
						'out_trade_no' => $recharge->out_trade_no,
						'operator'     => '[支付宝充值]',
						'value'        => $arr['total_amount'],
						'before'       => $member->cash,
						'after'        => $member->cash + $arr['total_amount'],
						'type'         => 1, //'支付类型 管理员充值:0 支付宝:1 微信:2'
						'remarks'      => '', //备注
					];
					CashLog::create( $cash_log_data );

					//保存用户 cash
					$member->cash = $member->cash + $arr['total_amount'];
					$member->save();

					//提交
					DB::commit();
					Log::channel( 'alipay' )->info( '异步通知 成功', [ 'order->out_trade_no' => $recharge->out_trade_no ] );
				} catch ( Exception $e ) {
					//回滚
					DB::rollback();
					Log::channel( 'alipay' )->error( '异步通知 失败回滚',
						[ 'order->out_trade_no' => $recharge->out_trade_no, $e ] );
					//throw $e;
				}
			}

		} else {
			Log::channel( 'alipay' )->error( '验签失败!', [ $arr ] );

			return '非法访问';
		}
	}

	// 同步跳转
	public function AliPay_Return_Url() {
		//			"charset" => "UTF-8"
//		  "out_trade_no" => "16105397483f0a155a50c60"
//		  "method" => "alipay.trade.wap.pay.return"
//		  "total_amount" => "0.01"
//		  "sign" => "o+5pEmyG3pM4N+8yAJMU+7mZwfLnRVEP/N6fennLF28dwsifqVGp6lvxjIDTG5bP47wBHHv2LvmI7QNqdeIJeqF2EyidSdhBtEZ9eUVF9EtfnYXVpICrXHP0YTDJF8DNhBNV23aMgbHJjdmCYe/G9JG4IuVI7SNI ▶"
//		  "trade_no" => "2021011322001486541406465631"
//		  "auth_app_id" => "2018042302593514"
//		  "version" => "1.0"
//		  "app_id" => "2018042302593514"
//		  "sign_type" => "RSA2"
//		  "seller_id" => "2088921500922163"
//		  "timestamp" => "2021-01-13 20:09:29"
		$arr = request()->all();
		//验签
		$res = @Factory::payment()->common()->verifyNotify( $arr );
		if ( $res ) {
			//验签成功

			$recharge = Recharge::where( 'out_trade_no', $arr['out_trade_no'] )->where( 'pay_status',
				false )->first();
			if ( $recharge ) {
				//开启事务
				DB::beginTransaction();
				try {
					$recharge->update( [ 'pay_status' => true, 'total_amount' => $arr['total_amount'] ] );
					$member = Member::where( 'id', $recharge->user_id )->first();


					//写支付日志
					$pay_log_data = [
						'user_id'      => $recharge->user_id,
						'out_trade_no' => $recharge->out_trade_no,
						'pay_type'     => 1, //'支付类型 管理员充值:0 支付宝:1 微信:2'
						'total_amount' => $recharge->total_amount,
					];
					PayLog::create( $pay_log_data );

					//写CASH 日志
					$cash_log_data = [
						'user_id'      => $recharge->user_id,
						'out_trade_no' => $recharge->out_trade_no,
						'operator'     => '[支付宝充值]',
						'value'        => $arr['total_amount'],
						'before'       => $member->cash,
						'after'        => $member->cash + $arr['total_amount'],
						'type'         => 1, //'支付类型 管理员充值:0 支付宝:1 微信:2'
						'remarks'      => '', //备注
					];
					CashLog::create( $cash_log_data );

					//保存用户 cash
					$member->cash = $member->cash + $arr['total_amount'];
					$member->save();

					//提交
					DB::commit();
					//Log::channel( 'alipay' )->info( 'Return_Url 成功', [ 'order->out_trade_no' => $recharge->out_trade_no ] );
				} catch ( Exception $e ) {
					//回滚
					//dd($e);
					DB::rollback();
					Log::channel( 'alipay' )->error( 'Return_Url 失败回滚',
						[ 'order->out_trade_no' => $recharge->out_trade_no ] );
					//throw $e;
				}

			}

		} else {
			//验签失败
			return redirect( url( '/funds/recharge' ) );
			//dd('非法访问!!');
		}

		//  funds/list      资金明细

		return redirect( url( '/funds/list' ) );
	}

	//订单查询
	function AliPay_Query() {
		$outTradeNo = request()->get( 'outTradeNo', '160850581269b8531f6ccf8' );
		try {
			$result = Factory::payment()->common()->query( $outTradeNo );
			if ( ! empty( $result->code ) && $result->code == 10000 ) {
				$res = 'msg:' . $result->msg . '</br>';
				$res .= '订单号:' . $result->outTradeNo . '</br>';
				$res .= '支付宝交易号:' . $result->tradeNo . '</br>';
				$res .= '购买者ID:' . $result->buyerLogonId . '</br>';
				$res .= '支付状态:' . $result->tradeStatus . '</br>';
				$res .= '发起时间:' . $result->sendPayDate . '</br>';

			} else {
				$res = "msg:" . $result->msg . '</br>' . "sub_msg:" . $result->subMsg . '</br>';
			}

		} catch ( Exception $e ) {
			$res = "调用失败，" . $e->getMessage() . PHP_EOL;
		}

		return $res;
	}

	//自主查询支付状态
	function AliPay_PayStatus() {
		$outTradeNo = request()->get( 'outTradeNo' );
		try {
			$result = Factory::payment()->common()->query( $outTradeNo );
			//tradeStatus: "TRADE_SUCCESS"
			if ( $result->tradeStatus == 'TRADE_SUCCESS' && $result->code == 10000 ) {
				$recharge = Recharge::where( 'out_trade_no', $outTradeNo )->where( 'pay_status', false )->first();
				if ( ! $recharge ) {
					return '已支付订单';
				}
				//开启事务
				DB::beginTransaction();
				try {
					//更新充值状态
					$recharge->update( [ 'pay_status' => true, 'total_amount' => $result->totalAmount ] );
					$member = Member::where( 'id', $recharge->user_id )->first();
					//写支付日志
					$pay_log_data = [
						'user_id'      => $recharge->user_id,
						'out_trade_no' => $recharge->out_trade_no,
						'pay_type'     => 1, //'支付类型 管理员充值:0 支付宝:1 微信:2'
						'total_amount' => $result->totalAmount,
					];
					PayLog::create( $pay_log_data );

					//写CASH 日志
					$cash_log_data = [
						'user_id'      => $recharge->user_id,
						'out_trade_no' => $recharge->out_trade_no,
						'operator'     => '[支付宝充值]',
						'value'        => $result->totalAmount,
						'before'       => $member->cash,
						'after'        => $member->cash + $result->totalAmount,
						'type'         => 1, //'支付类型 管理员充值:0 支付宝:1 微信:2'
						'remarks'      => '', //备注
					];
					CashLog::create( $cash_log_data );
					//保存 用户cash
					$member->cash = $member->cash + $result->totalAmount;
					$member->save();
					//提交
					DB::commit();

					return 'success';
				} catch ( Exception $e ) {
					//回滚
					DB::rollback();
					Log::channel( 'alipay' )->error( '自主查询支付状态失败!' );

					//dd($e->getMessage());
					return '自主查询支付状态失败!';
				}

			} else {
				if ( $result->tradeStatus == 'TRADE_CLOSED' ) {
					return "交易关闭";
				}

				return "msg:" . $result->msg . PHP_EOL . "sub_msg:" . $result->subMsg . PHP_EOL;
			}

		} catch ( Exception $e ) {
			return "调用失败，" . $e->getMessage() . PHP_EOL;
		}

	}

	//交易退款
	function AliPay_Refund() {
		$out_trade_no = request()->get( 'out_trade_no' );
		try {
			$recharge   = Recharge::where( 'out_trade_no', $out_trade_no )->where( 'pay_status', true )->first();
			$refund_log = RefundLog::where( 'out_trade_no', $out_trade_no )->where( 'type', 1 )->first();
			if ( $refund_log ) {
				return '已退款';
			}

			if ( ! $recharge ) {
				return '订单不存在';
			}
			$member = Member::where( 'id', $recharge->user_id )->first();
			if ( ! $member ) {
				return '用户不存在';
			}
			//发起退款
			$result = Factory::payment()->common()->refund( $out_trade_no, $recharge->total_amount );
			if ( ! empty( $result->code ) && $result->code == 10000 ) {
				if ( $result->fundChange == 'Y' ) {
					//fundChange == Y 退款请求成功
					//开启事务
					DB::beginTransaction();
					try {
						//写资金日志
						$cash_log_data = [
							'user_id'      => $recharge->user_id,
							'out_trade_no' => $recharge->out_trade_no,
							'operator'     => '[支付宝退款]',
							'value'        => $recharge->total_amount * - 1,
							'before'       => $member->cash,
							'after'        => $member->cash - $recharge->total_amount,
							'type'         => 12, //'支付类型 管理员充值:0 支付宝:1 微信:2   退款12'
							'remarks'      => '', //备注
						];
						CashLog::create( $cash_log_data );

						//写退款日志
						$refund_log_data = [
							'user_id'      => $member->id,
							'out_trade_no' => $out_trade_no,
							'trade_no'     => $result->tradeNo,
							'buyer_id'     => $result->buyerLogonId,
							'type'         => 1,  //1支付宝 2微信
							'total_amount' => $recharge->total_amount,
							'refund_time'  => $result->gmtRefundPay,
						];
						RefundLog::create( $refund_log_data );


						//更新余额
						$member->cash = $member->cash - $recharge->total_amount;
						$member->save();
						//更改退款状态
						$recharge->refund_status = true;
						$recharge->remarks       = '原路退款';
						$recharge->save();
						//提交
						DB::commit();

						//	Log::channel( 'alipay' )->info( '退款提交 成功', [ 'order->out_trade_no' => $order->out_trade_no ] );

						return 'success';
					} catch ( Exception $e ) {
						//回滚
						DB::rollback();
						$is_refund = $member->update( [ 'status' => 1 ] );
						Log::channel( 'alipay' )->error( '退款 失败回滚 ',
							[ 'order->out_trade_no' => $recharge->out_trade_no ] );
					}

				} else {
					return '已退款 订单号:' . $result->outTradeNo . PHP_EOL;
				}

			} else {
				return "msg:" . $result->msg . '</br>' . "sub_msg:" . $result->subMsg . '</br>';
			}

		} catch ( Exception $e ) {
			return "调用失败，" . $e->getMessage() . PHP_EOL;
		}
	}

}